package zip;
import Util.CreateFileUtil;
import net.jpountz.lz4.*;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Param;

import java.io.*;
import java.util.Base64;
import java.util.HashMap;

/**
 * Java LZ4 implementations test
 */
public class Lz4Test extends TestParent {
    // 压缩等级，以时间换空间
    @Param({"1", "2", "3", "4", "5", "6", "7", "8", "9"})
    public int LEVEL;

    @Param({"fastBLOCK_64K", "fastBLOCK_128K", "fastMAX_BLOCK_SIZE", "highBLOCK_64K"})
    public String Lz4BLOCK;

    final int BLOCK_64K = 64 * 1024;
    final int BLOCK_128K = 128 * 1024;
    final int MAX_BLOCK_SIZE = 32 * 1024 * 1024;

    static HashMap<Integer, byte[]> compressFile;
    static HashMap<Integer, byte[]> deCompressFile;
    static {
        compressFile = new HashMap<Integer, byte[]>();
        deCompressFile = new HashMap<Integer, byte[]>();
        for (int i = 1; i < 10; i++) {
            compressFile.put(i,CreateFileUtil.getBytesByFile("./test/test_"+i+".json"));
            deCompressFile.put(i,CreateFileUtil.getBytesByFile("./test/test_"+i+".Lz4.highBLOCK_64K"));
        }
    }

    @Benchmark
    public byte[] compress() throws IOException {
        ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
        LZ4BlockOutputStream compressedOutput ;
        switch (Lz4BLOCK) {
            case "fastBLOCK_64K":

                compressedOutput = new LZ4BlockOutputStream(byteOutput, BLOCK_64K, LZ4Factory.nativeInstance().fastCompressor());
                break;
            case "fastBLOCK_128K":
                compressedOutput = new LZ4BlockOutputStream(byteOutput, BLOCK_128K, LZ4Factory.nativeInstance().fastCompressor());
                break;
            case "fastMAX_BLOCK_SIZE":
                compressedOutput = new LZ4BlockOutputStream(byteOutput, MAX_BLOCK_SIZE, LZ4Factory.nativeInstance().fastCompressor());
                break;
            default:
                compressedOutput = new LZ4BlockOutputStream(byteOutput, BLOCK_64K, LZ4Factory.nativeInstance().highCompressor());
                break;
        }
        compressedOutput.write(compressFile.get(LEVEL));
        compressedOutput.close();
        byte[] outdata = Base64.getEncoder().encode(byteOutput.toByteArray());
        CreateFileUtil.bytes2File(outdata, "./test/", "test_" + LEVEL + ".Lz4" + "." + Lz4BLOCK);
        return outdata;
    }

    @Benchmark
    public byte[] deCompress() {
        int level = LEVEL;
        LZ4BlockInputStream inStream = new LZ4BlockInputStream( new ByteArrayInputStream(Base64.getDecoder().decode(deCompressFile.get(level))));
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = inStream.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            byte[] data = bos.toByteArray();
            bos.close();
            inStream.close();
            CreateFileUtil.bytes2File(data,"./test/","test_"+level+".Lz4.json");
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
